package com.qf.fmcommodity.user.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.qf.fmcommodity.user.entity.*;
import com.qf.fmcommodity.user.mapper.OrdersMapper;
import com.qf.fmcommodity.user.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmcommodity.user.utils.DateFormatUtil;
import com.qf.fmcommodity.user.utils.WxpayUtils;
import com.qf.fmcommodity.user.vo.AddOrderReturnVo;
import com.qf.fmcommodity.user.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author 苇名一心
 * @since 2023-02-13
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    IOrderItemService iOrderItemService;

    @Autowired
    IShoppingCartService iShoppingCartService;

    @Autowired
    IProductService productService;

    @Autowired
    IProductImgService iProductImgService;

    @Autowired
    IProductSkuService iProductSkuService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AddOrderReturnVo add(String[] cids, Orders orders) throws Exception {

        //生成订单编号
        String s = UUID.randomUUID().toString();
        String oId = s.replaceAll("-", "");
        //挂载id
        orders.setOrderId(oId);
        orders.setCreateTime(new Date());
        orders.setUpdateTime(new Date());
        //落库
        save(orders);

        //根据参数获取购物车信息数据
        List<ShoppingCart> shoppingCartList = iShoppingCartService.list(new QueryWrapper<ShoppingCart>().in("cart_id", cids));
        Product product = null;
        for (ShoppingCart shoppingCart : shoppingCartList) {
            product = productService.getOne(new QueryWrapper<Product>().eq("product_id", shoppingCart.getProductId()));

            ProductImg productImg = iProductImgService.getOne(new QueryWrapper<ProductImg>().eq("item_id", shoppingCart.getProductId()).eq("is_main",1));

            ProductSku productSku = iProductSkuService.getOne(new QueryWrapper<ProductSku>().eq("sku_id", shoppingCart.getSkuId()));

            //订单项id
            String itId = UUID.randomUUID().toString().replace("-", "");

            OrderItem orderItem = new OrderItem();
            //添加数据
            orderItem.setItemId(itId);
            orderItem.setOrderId(oId);
            orderItem.setProductId(shoppingCart.getProductId());
            orderItem.setProductName(product.getProductName());
            orderItem.setProductImg(productImg.getUrl());
            orderItem.setSkuId(productSku.getSkuId());
            orderItem.setSkuName(productSku.getSkuName());
            orderItem.setProductPrice(shoppingCart.getProductPrice());
            orderItem.setBuyCounts(Integer.valueOf(shoppingCart.getCartNum()));
            orderItem.setTotalAmount(new BigDecimal(orderItem.getBuyCounts()).multiply(orderItem.getProductPrice()));
            orderItem.setBasketDate(DateFormatUtil.stringToDate(shoppingCart.getCartTime()));
            orderItem.setBuyTime(new Date());
            orderItem.setIsComment(0);
            iOrderItemService.save(orderItem);

            UpdateWrapper<ProductSku> wrapper = new UpdateWrapper<ProductSku>().set("stock", productSku.getStock() - 1).eq("sku_id", productSku.getSkuId());
            iProductSkuService.update(wrapper);
        }

        iShoppingCartService.removeBatchByIds(shoppingCartList);

        String url = getWeixinPayUrl(oId);

        AddOrderReturnVo vo = new AddOrderReturnVo();
        vo.setOrderId(oId);
        vo.setProductNames("aseraer");
        vo.setPayUrl(url);

        return vo;
    }

    @Override
    public String status(String oId) throws Exception {
        String s = WxpayUtils.queryOrder(oId);

        if (s!=null&&s.equals("SUCCESS")) {

            //修改订单表信息
            final Orders orders = new Orders();
            orders.setOrderId(oId);
            orders.setStatus("2");
            orders.setPayTime(new Date());
            orders.setUpdateTime(new Date());

            updateById(orders);
            return "2";
        }

        return "-1";
    }

    @Override
    public AddOrderReturnVo addCopy(String[] cids, Orders orders) throws Exception {
        //1.查询用户购物车中对应的商品套餐库存量是否还足够
        //如果库存够，则继续下单流程：如果库存量不足，直接抛出异常；任何一个商品的库存不足都算失败
        //listbycids(数组id)返回值List<ShoppingCart>
        List<ShoppingCart> shoppingCartList = iShoppingCartService.listbycids(cids);

        //校验库存
        verifyStock(shoppingCartList);

        //2.生成唯一的订单编号
        String oid = UUID.randomUUID().toString().replaceAll("-", "");

        //3.生成订单表（orders表）中的数据
        orders.setOrderId(oid);
        orders.setCreateTime(new Date());
        orders.setUpdateTime(new Date());
        //落库
        save(orders);

        //string,名字1，名字2
        String productNames = shoppingCartList.stream().map(ShoppingCart::getProductName).collect(Collectors.joining(","));
        //4.生成订单明细表的数据（orderItem表）
        //购物车中有几条数据，订单明细表就有几条数据
        for (ShoppingCart shoppingCart : shoppingCartList) {
            Product product = productService.getOne(new QueryWrapper<Product>().eq("product_id", shoppingCart.getProductId()));

            ProductImg productImg = iProductImgService.getOne(new QueryWrapper<ProductImg>().eq("item_id", shoppingCart.getProductId()).eq("is_main",1));

            ProductSku productSku = iProductSkuService.getOne(new QueryWrapper<ProductSku>().eq("sku_id", shoppingCart.getSkuId()));

            //订单项id
            String itId = UUID.randomUUID().toString().replace("-", "");

            OrderItem orderItem = new OrderItem();
            //添加数据
            orderItem.setItemId(itId);
            orderItem.setOrderId(oid);
            orderItem.setProductId(shoppingCart.getProductId());
            orderItem.setProductName(product.getProductName());
            orderItem.setProductImg(productImg.getUrl());
            orderItem.setSkuId(productSku.getSkuId());
            orderItem.setSkuName(productSku.getSkuName());
            orderItem.setProductPrice(shoppingCart.getProductPrice());
            orderItem.setBuyCounts(Integer.valueOf(shoppingCart.getCartNum()));
            orderItem.setTotalAmount(new BigDecimal(orderItem.getBuyCounts()).multiply(orderItem.getProductPrice()));
            orderItem.setBasketDate(DateFormatUtil.stringToDate(shoppingCart.getCartTime()));
            orderItem.setBuyTime(new Date());
            orderItem.setIsComment(0);
            iOrderItemService.save(orderItem);

        }
        //5.删除用户购物车中的cids对应数据
        iShoppingCartService.removeBatchByIds(shoppingCartList);
        //6.跟微信支付平台交互，获取可以支付的url
        String url = getWeixinPayUrl(oid);


        //7.组织返回的数据
        AddOrderReturnVo vo = new AddOrderReturnVo();
        vo.setOrderId(oid);
        vo.setProductNames(productNames);
        vo.setPayUrl(url);
        return vo;
    }

    /**
     * 校验库存量，如果不够则抛出异常
     * @param shoppingCartList
     */
    private void verifyStock(List<ShoppingCart> shoppingCartList) throws Exception {
        //分组sku_id
        Map<String, List<ShoppingCart>> map = shoppingCartList.stream().collect(Collectors.groupingBy(ShoppingCart::getSkuId));
        //遍历map
        for (Map.Entry<String, List<ShoppingCart>> entry : map.entrySet()) {

            //key值
            String skuid = entry.getKey();

            //value
            List<ShoppingCart> value = entry.getValue();

            Integer stock = value.get(0).getStock();

            //summingInt合计购买量
            Integer totalNum = value.stream().collect(Collectors.summingInt(value1 -> Integer.valueOf(value1.getCartNum())));

            //判断
            if (stock < totalNum) {
                throw new Exception("库存不足");
            }
            //更新库存
            ProductSku productSku = new ProductSku();
            productSku.setSkuId(skuid);
            productSku.setStock(stock-totalNum);
            iProductSkuService.updateById(productSku);
        }

    }


    private String getWeixinPayUrl(String oId) throws Exception {
        String payUrl = WxpayUtils.getPayUrl(oId);

        return payUrl;
    }


}
